[이코테-구현]_게임 개발


문제 설명

문제 순서에 따라 알고리즘을 구현하는 대표적인 시뮬레이션(구현) 문제이다.
n, m 크기의 맵 안에서 각 조건에 맞게 움직일 수 있는 총 개수를 맞추는 문제이다.

움직일 수 있는 조건

  1. 현 위치(x, y), 바라보고 있는 방향(direction)에서 반시계방향(왼쪽)을 바라보았을 때, **바다가 아니거나 한번도 방문한 적이 없는 칸이면 한 칸 이동
  2. 만약 못간다면, 왼쪽으로 한번 더 돌아 1번 반복
  3. 더이상 갈 곳이 없다면, 현재 바라보고 있는 방향에서 뒤로 한칸 이동
  4. 뒤로도 이동할 수 없다면 게임 종료

My Solution

# 맵의 크기
n, m = map(int, input().split())
# 나의 위치
x, y, direction = map(int, input().split())
# 방문 기록 초기화
d = [[0] * m for _ in range(n)]
d[x][y] = 1

# 맵의 상태
arr = []
for _ in range(n):
    arr.append(list(map(int, input().split())))

# 북, 서, 남, 동 방향 초기화
dx = [-1, 0, 1, 0] # row
dy = [0, -1, 0, 1] # col

# count, 회전 횟수 초기화
count = 1
turn_time = 0

# 왼쪽으로 회전
def turn_left():
    global direction
    direction -= 1
    if direction == -1:
        direction = 3

while True:
    turn_left()
    nx = x + dx[direction]
    ny = y + dy[direction]
    # 방문한 곳이 아니고 and 육지인 상태라면 전진
    if d[nx][ny] == 0 and arr[nx][ny] == 0:
        d[nx][ny] = 1
        count += 1
        x, y = nx, ny
        continue
    else:
        turn_time += 1

    if turn_time == 4:
        nx = x - dx[direction]
        ny = y - dy[direction]
        # 육지라면 뒤로 한 칸 이동
        if arr[nx][ny] == 0:
            x, y = nx, ny
        else:
            break
        turn_time = 0

print(count)

문제 풀이

  • 구현(시뮬레이션) 문제에 대한 경험이 적어 푸는데 익숙치 않아 풀이를 보고 로직을 이해한 뒤, 주석을 달아가며 안보고 다시 풀어보았다.
  • 문제에 제시 된 대로 로직이 짜여져 있으며, 간단하게 설명하자면 방문 기록을 하나씩 체크하면서 방향에 대한 카운트가 네 방향을 모두 충족하게 됬을 시, 갈 곳이 없다면 종료하는 로직이다.

이코테 풀이

n, m = map(int, input().split())     # 맵의 크기
x, y, direction = map(int, input().split())
d = [[0] * m for _ in range(n)] # 맵의 방문 상태 초기화
d[x][y] = 1 # 맵의 첫 위치 방문 표시

# 맵의 상태를 표시
array = []
for _ in range(n):
    array.append(list(map(int, input().split())))

# 북, 동, 남, 서 방향 정의
dx = [-1, 0, 1, 0] # 행
dy = [0, 1, 0, -1] # 열

# 왼쪽으로 회전
def turn_left():
    global direction
    direction -= 1
    if direction == -1:
        direction = 3

# 시뮬레이션 시작
count = 1
turn_time = 0
while True:
    # 왼쪽으로 회전
    turn_left()
    nx = x + dx[direction]
    ny = y + dy[direction]
    # 회전한 이후 정면에 가보지 않은 칸이 존재하는 경우 이동
    if d[nx][ny] == 0 and array[nx][ny] == 0:
        d[nx][ny] = 1
        x = nx
        y = ny
        count += 1
        turn_time = 0
        continue
    # 회전한 이후 정면에 가보지 않은 칸이 없거나 바다인 경우
    else:
        turn_time += 1
    # 네 방향 모두 갈 수 없는 경우
    if turn_time == 4:
        nx = x - dx[direction]
        ny = y - dy[direction]
        # 뒤로 갈 수 있다면 이동하기
        if array[nx][ny] == 0:
            x = nx
            y = ny
        else:
            break
        turn_time = 0

print(count)

Hello, I'm@nickhealthy
개발자를 꿈꾸고, 파이썬과 클라우드에 관심이 많은 비전공자

Github